﻿using System;
using System.Linq;
using System.Reflection;
using Nomad.WebSync.Extensions;

namespace Nomad.WebSync.Service.DAO {
    internal partial class Account {
        /// <summary>
        /// Copy all property values from a non-attached instance from this instance
        /// </summary>
        /// <param name="instance">Source instance of Contact</param>
        public void Copy(Account instance) {
            // Get a list of properties from this class
            PropertyInfo[] properties = instance.GetType().GetProperties();
            foreach (var property in properties) {
                // With the property can be read and write
                if (property.CanRead && property.CanWrite) {
                    // Get the value of source instance for this property
                    var propertyValue = property.GetValue(instance, null);
                    // Set the value on current instance of this property
                    property.SetValue(this, propertyValue, null);
                }
            }
        }

        public Account Clone() {
            Account result = new Account();
            // Get a list of properties from this class
            PropertyInfo[] properties = typeof(Account).GetProperties();
            foreach (var property in properties) {
                // With the property can be read and write
                if (property.CanRead && property.CanWrite) {
                    // Get the value of source instance for this property
                    var propertyValue = property.GetValue(this, null);
                    // Set the value on current instance of this property
                    property.SetValue(result, propertyValue, null);
                }
            }
            return result;
        }

        public void SetDeviceID(string guid) {
            using (var context = new WebSyncDataContext()) {
                var account = context.Accounts.SingleOrDefault(query => query.ID == this.ID);
                if (account != null) {
                    account.DeviceID = guid;
                    context.SubmitChanges();
                }
            }
        }

        public void SetOwnerInformation(string name, string company, string address, string email, string phone) {
            using (var context = new WebSyncDataContext()) {
                var account = context.Accounts.SingleOrDefault(query => query.ID == this.ID);
                if (account != null) {
                    account.Name = name;
                    account.Company = company;
                    account.Address = address;
                    account.Email = email;
                    account.Phone = phone;
                    context.SubmitChanges();
                }
            }
        }

        public static void CreateAccount(string username, string password, string email) {
            using (var context = new WebSyncDataContext()) {
                // Verify is unique username
                var exists = context.Accounts.SingleOrDefault(query => query.Username == username);
                if (exists != null)
                    throw new Exception("Username already exists.");

                // Insert new account with storage the hash of password
                var account = new Account() {
                    Email = email,
                    Username = username,
                    Password = password.Hash()
                };

                context.Accounts.InsertOnSubmit(account);
                context.SubmitChanges();
            }
        }

        public static bool Exists(string username, string password) {
            using (var context = new WebSyncDataContext()) {
                var query = from account in context.Accounts
                            where
                                (account.Username == username) &&
                                (account.Password == password.Hash())
                            select account;

                return (query.SingleOrDefault() != null);
            }
        }

        public static Account GetAccountByUser(string username) {
            using (var context = new WebSyncDataContext()) {
                return context.Accounts.SingleOrDefault(query => query.Username == username);
            }
        }
        
        public static Account GetOwnerByUser(string username) {
            using (var context = new WebSyncDataContext()) {
                return context.Accounts.SingleOrDefault(query => query.Username == username);
            }
        }
    }
}
